package com.hyfd.task;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.SSLContext;
import javax.security.cert.CertificateException;
import javax.security.cert.X509Certificate;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.hyfd.common.GenerateData;
import com.hyfd.common.utils.DateTimeUtils;
import com.hyfd.common.utils.MD5;
import com.hyfd.common.utils.XmlUtils;
import com.hyfd.dao.mp.DixintongKeyDao;
import com.hyfd.dao.mp.ProviderPhysicalChannelDao;

@Component
public class DixintongKeyTask {

	private static int OUT_TIME = 30000;//超时时间
	private static Logger log = Logger.getLogger(DixintongKeyTask.class);//日志
	@Autowired
	ProviderPhysicalChannelDao providerPhysicalChannelDao;//物理通道信息
	@Autowired
	DixintongKeyDao dixintongKeyDao;//迪信通密钥key
	
//	@Scheduled(cron="0 0 1 * * ?")//密钥更新时间待定
	public void saveDixintongKey(){
		String id = "dixintong";
		try{
			Map<String,Object> channel = providerPhysicalChannelDao.selectByPrimaryKey(id);
			String linkUrl = (String) channel.get("link_url");//充值地址
			String defaultParameter = (String) channel.get("default_parameter");//默认参数
			Map<String,String> paramMap = XmlUtils.readXmlToMap(defaultParameter.trim());
			String appKey = paramMap.get("appId");// 分配给第三方系统的AppKey
			String version = paramMap.get("version");// 接口版本
			Map<String,Object> key = dixintongKeyDao.selectRecentKey();
			String secretKey = (String) key.get("secret_key");//获取最新密钥
			String reqTime = DateTimeUtils.formatDate(new Date(), "yyyyMMddHHmmss");// 请求时间
			String curids = appKey+DateTimeUtils.formatDate(new Date(), "yyyyMMddHHmmssSSS") + GenerateData.getIntData(9,9);// 交易流水号，每笔交易均不一样
			String xml = createMiyaoXML(appKey, secretKey, curids, reqTime, version);//获取提交参数
			String resultData = sslPost(linkUrl,xml);//结果
			if(resultData!=null&&!resultData.equals("")){
				Map<String,String> resultMap = XmlUtils.readXmlToMap(resultData.trim());
				Map<String,Object> map = new HashMap<String,Object>();
				map.put("expired", resultMap.get("expired"));
				map.put("secretKey", resultMap.get("secretKey"));
				dixintongKeyDao.insertSelective(map);
			}
		}catch(Exception e){
			log.error("迪信通获取密钥的调度错误"+e.getMessage());
		}
	}
	
	public static String createMiyaoXML(String appKey, String secretKey, String transactionId, String reqTime, String version) {
		StringBuffer signXml = new StringBuffer();
		signXml.append("<Body>");
		signXml.append("</Body>");
		String signStr = transactionId + "" + signXml + "" + secretKey;
		String sign = null;
		try {
			sign = MD5.ToMD5(signStr);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("|"+e.getMessage());
		}

		StringBuffer xml = new StringBuffer();
		xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
		xml.append("<Root>");
		xml.append("<Head>");
		xml.append("<appKey>" + appKey + "</appKey>");
		xml.append("<method>sys.getSecretKey</method>");
		xml.append("<transactionId>" + transactionId + "</transactionId>");
		xml.append("<reqTime>" + reqTime + "</reqTime>");
		xml.append("<sign>" + sign + "</sign>");
		xml.append("<version>V1.0</version>");
		xml.append("</Head>");
		String str = xml.toString() + signXml.toString() + "</Root>";
		return str;
	}
	
	/**
	 * 进行HttpClient post连接
	 * 
	 * @param isHttps
	 *            是否ssl链接
	 * @param url
	 * @param data
	 * @param contentType
	 * @return
	 */
	public String sslPost(String url, String data) {
		CloseableHttpClient httpClient = createSSLInsecureClient();
		HttpPost httpPost = new HttpPost(url);
		if (null != data) {
			StringEntity stringEntity = new StringEntity(data, "UTF-8");
			stringEntity.setContentEncoding("UTF-8");
			stringEntity.setContentType("application/xml");
			httpPost.setEntity(stringEntity);
		}

		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(OUT_TIME).setConnectTimeout(OUT_TIME).build();// 设置请求和传输超时时间
		httpPost.setConfig(requestConfig);

		try {
			HttpResponse response = httpClient.execute(httpPost);
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				String out = EntityUtils.toString(entity, "UTF-8");
				return out;
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error("dixintong sslPost error|"+e.getMessage());
		} 

		return null;
	}

	/**
	 * HTTPS访问对象，信任所有证书
	 * 
	 * @return
	 */
	public CloseableHttpClient createSSLInsecureClient() {
		try {
			SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
				// 信任所有
				@SuppressWarnings("unused")
				public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
					return true;
				}

				@Override
				public boolean isTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
						throws java.security.cert.CertificateException {
					// TODO Auto-generated method stub
					return false;
				}
			}).build();
			SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
			return HttpClients.custom().setSSLSocketFactory(sslsf).build();
		} catch (Exception e) {
			e.printStackTrace();
			log.error("dixintong createSSLInsecureClient error|"+e.getMessage());
		} 
		return HttpClients.createDefault();
	}
}
